package com.mrd.gtimpframe.service.impl;

import com.github.pagehelper.PageInfo;
import com.mrd.gtimpframe.entity.Dictionary;
import com.mrd.gtimpframe.entity.DictionaryGroup;
import com.mrd.gtimpframe.repository.DictionaryMapper;
import com.mrd.gtimpframe.service.DictionaryGroupService;
import com.mrd.gtimpframe.service.DictionaryService;
import com.mrd.redis.JedisClientClusterImpl;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service(value = "dictionaryService")
public class DictionaryServiceImpl implements DictionaryService {
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Autowired
    private JedisClientClusterImpl jedisClientCluster;
    @Autowired
    private DictionaryGroupService dictionaryGroupService;

    @Override
    public int deleteByPrimaryKey(String id) {
        Dictionary dictionary = this.selectByPrimaryKey(id);
        int i = dictionaryMapper.deleteByPrimaryKey(id);
        if (i > 0 && dictionary != null) {
            updateRedis(dictionary.getGroupId());
        }
        return i;
    }

    @Override
    public int insert(Dictionary record) {
        int i = dictionaryMapper.insert(record);
        if (i > 0) {
            updateRedis(record.getGroupId());
        }
        return i;
    }

    @Override
    public int insertSelective(Dictionary record) {
        int i = dictionaryMapper.insertSelective(record);
        if (i > 0) {
            updateRedis(record.getGroupId());
        }
        return i;
    }

    @Override
    public Dictionary selectByPrimaryKey(String id) {
        return dictionaryMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Dictionary record) {
        int i = dictionaryMapper.updateByPrimaryKeySelective(record);
        if (i > 0) {
            updateRedis(record.getGroupId());
        }
        return i;
    }

    @Override
    public int updateByPrimaryKey(Dictionary record) {
        int i = dictionaryMapper.updateByPrimaryKey(record);
        if (i > 0) {
            updateRedis(record.getGroupId());
        }
        return i;
    }

    @Override
    public List<Dictionary> selectByGroupId(String groupId, boolean justValid) {
        List<Dictionary> dictionaryList = jedisClientCluster
                .range("dictionary_" + groupId, 0, -1, Dictionary.class);
        if (dictionaryList == null || dictionaryList.size() == 0) {
            dictionaryList = dictionaryMapper.selectByGroupId(groupId);
            jedisClientCluster
                    .rightPushAll("dictionary_" + groupId, dictionaryList, null, TimeUnit.SECONDS);
        }
        if (justValid) {
            Iterator<Dictionary> it = dictionaryList.iterator();
            while(it.hasNext()){
                Dictionary dictionary = it.next();
                if ("2".equals(dictionary.getStatus())){
                    it.remove();
                }
            }
        }
        return dictionaryList;
    }

    @Override
    public Page<Map<String, Object>> listPageData(Pageable page, Map<String, Object> params) {
        List<Map<String, Object>> pageMapList = dictionaryMapper.listSelective(params);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo(pageMapList);
        return new PageImpl<Map<String, Object>>(pageMapList, page, pageInfo.getTotal());
    }

    @Override
    public int updateDeleteStateByPrimaryKey(String id) {
        if (StringUtils.isNotEmpty(id)) {
            Dictionary dictionary = this.selectByPrimaryKey(id);
            if (dictionary != null) {
                dictionary.setStatus("2");
                return this.updateByPrimaryKey(dictionary);
            }
        }
        return 0;
    }

    /**
     * 通过字典组Code获取字典
     * 先将code转为id，再从redis中获取字典
     *
     * @param groupCodes 字典组Code 支持多个code
     */
    @Override
    public List<Dictionary> selectWithDictionaryByCodesIn(String... groupCodes) {
        List<DictionaryGroup> allGroup = dictionaryGroupService.selectAll(true);
        List<String> targetGids = new ArrayList<>();
        List<Dictionary> targetDictionaryList = new ArrayList<>();
        flag:for (DictionaryGroup group : allGroup) {
            for (String code : groupCodes) {
                if (code.equals(group.getCode())) {
                    targetGids.add(group.getId());
                    break flag;
                }
            }
        }
        for (String gid : targetGids) {
            targetDictionaryList.addAll(this.selectByGroupId(gid, true));
        }
        return targetDictionaryList;
    }

    /**
     * 通过字典组ID获取字典
     *
     * @param ids 字典组id 支持多个id
     */
    @Override
    public List<Dictionary> selectWithDictionaryByPrimaryKey(String... ids) {
        List<Dictionary> targetDictionaryList = new ArrayList<>();
        for (String gid : ids) {
            targetDictionaryList.addAll(this.selectByGroupId(gid, true));
        }
        return targetDictionaryList;
    }

    public List<Dictionary> selectByPrimaryKeyArray(String... ids) {
        List<Dictionary> allValidDictionary = jedisClientCluster
                .range("all_dictionary", 0, -1, Dictionary.class);
        List<Dictionary> targetDictionaryList = new ArrayList<>();
        if (CollectionUtils.isEmpty(allValidDictionary)) {
            jedisClientCluster.delete("all_dictionary");
            allValidDictionary = dictionaryMapper.selectAll("1");
            allValidDictionary.addAll(dictionaryMapper.selectAll("0"));
            jedisClientCluster
                    .rightPushAll("all_dictionary", allValidDictionary, null, TimeUnit.SECONDS);
        }
        for (Dictionary dictionary : allValidDictionary) {
            for (String id : ids) {
                if (id == null) {
                    continue;
                }
                if (id.equals(dictionary.getId())) {
                    targetDictionaryList.add(dictionary);
                    break;
                }
            }
        }
        return targetDictionaryList;
    }

    private void updateRedis(String groupId) {
        jedisClientCluster.delete("dictionary_" + groupId);
        jedisClientCluster.rightPushAll("dictionary_" + groupId, dictionaryMapper.selectByGroupId(groupId), null, TimeUnit.SECONDS);

        jedisClientCluster.delete("all_dictionary");
        List<Dictionary> allValidDictionary = new ArrayList<>();
        allValidDictionary = dictionaryMapper.selectAll("1");
        allValidDictionary.addAll(dictionaryMapper.selectAll("0"));
        jedisClientCluster
                .rightPushAll("all_dictionary", allValidDictionary, null, TimeUnit.SECONDS);
    }
}
